{-# LANGUAGE DeriveDataTypeable #-}
----------------------------------------------------------------
--                                                            --
-- Module      :  LLVM.Code.Symbolic                        --
-- License     :  GPL3                                        --
-- Mantainer   :  Mikhail Belyaev                             --
--                                                            --
----------------------------------------------------------------

module LLVM.Code.Symbolic where

import qualified Data.DataMap as M
import LLVM.Parser.Record.Record
       (recordAsList, fromData, RawBlock(..), BlockHeader(..),
        BlockType(..))

import Data.Generics(Typeable, Data)
import LLVM.Util

type SymbolicTable = M.Map Integer String


newtype TypeSymbolTable = TypeSymbolTable{typeNames :: SymbolicTable}  deriving (Show,Eq,Typeable,Data)
data ValSymbolTable = ValSymbolTable{varNames :: SymbolicTable, bbNames :: SymbolicTable} deriving (Show,Eq,Typeable,Data)

instance BlockType TypeSymbolTable where
    fromRawBlock rb | rb.$header.$blockId == 13 = Just $ TypeSymbolTable $
                                                    M.fromList $ maybeFilter getName recs
        where recs = maybeFilter fromData $ rb.$contents
              getName rr = case (recordAsList rr) of
                                (_:1:id:syms) -> Just $ (id,massOrd syms)
                                otherwise -> Nothing
    fromRawBlock _ = Nothing

instance BlockType ValSymbolTable where
    fromRawBlock rb | rb.$header.$blockId == 14 = Just $ ValSymbolTable
                                                    (M.fromList $ maybeFilter getvrName recs)
                                                    (M.fromList $ maybeFilter getbbName recs)
        where recs = maybeFilter fromData $ rb.$contents
              getvrName rr = case (recordAsList rr) of
                                  (_:1:id:syms) -> Just $ (id,massOrd syms)
                                  otherwise -> Nothing
              getbbName rr = case (recordAsList rr) of
                                  (_:2:id:syms) -> Just $ (id,massOrd syms)
                                  otherwise -> Nothing
    fromRawBlock _ = Nothing

emptyMap = M.fromList []

emptyTS = TypeSymbolTable emptyMap
emptyVS = ValSymbolTable emptyMap emptyMap



